package com.example.gomi.intelligentcitypipe.serial;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.util.Log;

import com.example.gomi.intelligentcitypipe.bean.Response;
import com.example.gomi.intelligentcitypipe.utils.ResponseMessageUtils;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class BluetoothInterface implements OddSetInterface {


    private BluetoothDevice device = null;
    private BluetoothSocket socket;
    private OutputStream outputstream = null;
    private InputStream inputstream = null;

    private BluetoothAdapter mBluetoothAdapter = null;


    private static final String BLUETOOTH_ADR = "AB:B3:49:57:34:02";

    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private ConnectThread mConnectThread;

    //当前传感器设备的个数，即要开启的线程个数，用于设置线程数组的大小
    //这里默认为1，因为我们目前只需要和一个传感器连接， 比如：你要连接两个硬件设备，那就设置值为2，这样就会开启两个线程，分别去执行想要操作

    private ReadThread mReadThread = new ReadThread();// 请求连接的监听进程 private BlockingQueue<Byte[]> queue = new LinkedBlockingQueue<Byte[]>();// 内存缓冲区

    BlockingQueue<byte[]> messageQueue = new LinkedBlockingQueue<>();

    private SendThread sendThread = new SendThread();

    private Boolean connecting = true;
    private String version  = null;

    public BluetoothInterface(String version) {
        this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        Log.d("bluetooth", mBluetoothAdapter.getAddress());
        this.version = version;
    }


    /*write data*/
    public byte SendData(byte[] buffer) {
        this.messageQueue.add(buffer);
        return 1;
    }

    private void initBluetoothRelative() {
        if (device == null) {
            device = mBluetoothAdapter.getRemoteDevice(BLUETOOTH_ADR);
            if (device != null) {
                try {
                    if (mConnectThread == null) {
                        mConnectThread = new ConnectThread();
                    }
                    mConnectThread.start();

                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e("Bluetooth", "connect error." + e.getMessage());
                }
            } else {
                Log.e("BLUETOOTH", "Can not found the device.");
            }
            if (sendThread != null) {
                sendThread.start();
            }

            if(mReadThread!=null){
                mReadThread.start();
            }

        }
    }

    private class ConnectThread extends Thread {

        public ConnectThread() {

        }

        public void run() {
            if (SerialController.getInstance().getmRunFlag()&&SerialController.getInstance().getVersion().equals(BluetoothInterface.this.version)) {
                setName("ConnectThread");
                try {
                    //当连接成功，取消蓝牙适配器搜索蓝牙设备的操作，因为搜索操作非常耗时
                    if (socket == null) {
                        socket = device.createRfcommSocketToServiceRecord(MY_UUID);// Get a BluetoothSocket for a connection with the given BluetoothDevice
                    }
                    mBluetoothAdapter.cancelDiscovery();// Always cancel discovery because it will slow down a connection
                    socket.connect();// This is a blocking call and will only return on a successful connection or an exception
                    Log.e("Bluetooth", "Bluetooth connected ok.");
                    BluetoothInterface.this.initStream();
                } catch (IOException e) {
                    Log.e("ConnectThread", "socket connect error." + e.getMessage());
                    try {
                        socket.close();
                    } catch (IOException e2) {
                        Log.e("ConnectThread", "close error." + e.getMessage());
                        // e2.printStackTrace();
                    }
                    // 引用来说明要调用的是外部类的方法 run
                    BluetoothInterface.this.startConnect();
                    return;
                }
            }

        }

    }

    private void initStream() {
        try {
            this.inputstream = this.socket.getInputStream();

        } catch (Exception e) {

        }
        try {
            this.outputstream = this.socket.getOutputStream();
        } catch (Exception e) {

        }

    }

    public void startConnect() {
        this.mConnectThread.start();
    }

    public void start() {
        this.initBluetoothRelative();
    }

    public void close(Closeable... closeables) {
        if (closeables != null) {
            for (Closeable closeable : closeables) {
                try {
                    closeable.close();
                } catch (Exception e) {

                }
            }
        }
    }


    public BluetoothSocket getSocket() {
        if (socket == null) {
            try {
                socket = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (Exception ee) {
                Log.e("Bluetooth", "create socket error.");
            }

        }
        return socket;
    }


    /**
     * 读取管道数据
     */
    private class ReadThread extends Thread {
        private static final String TAG = "ReadThread";
        private byte[] ONE_BYTE = new byte[1];

        //private int index;
        public ReadThread() {
        }

        public void run() {
            //一次循环形成一个
            Log.e(TAG, "开启读取进程");
            while (SerialController.getInstance().getmRunFlag()&&SerialController.getInstance().getVersion().equals(BluetoothInterface.this.version)) {
                Log.e(TAG, "开启读取进程 while");
                Response response = new Response();
                try {
                    int index = 0;
                    InputStream inputStream = this.getInputStream();
                    //首先读取消息头 byte

                    while (index < Response.HEAD_LENGTH) {
                        if (inputStream.read(ONE_BYTE) > 0) {
                            Log.e(TAG, "read byte:" + ResponseMessageUtils.bytesToHex(ONE_BYTE));
                            if (PipeProtocol.RECEIVE_HEAD[index] == ONE_BYTE[0]) {
                                response.getHead()[index] = ONE_BYTE[0];
                                index++;
                            } else {
                                //不等的时候重置回原点
                                index = 0;
                            }

                        }
                    }
                    Log.e(TAG, "read byte header ok.");
                    //读取body , == 说明头是读取完整了的
                    if (index == Response.HEAD_LENGTH) {
                        int len;
                        int count = 0;
                        //count -> off
                        while ((len = inputStream.read(response.getBody(), count, Response.BODY_LENGTH - count)) > 0) {
                            //读完14个字节就跑吧,
                            if (count + len == Response.BODY_LENGTH) {
                                //通知控制器处理响应消息
                                SerialController.getInstance().handleResponse(response);
                                break;
                            }
                            count += len;
                        }

                    }

                } catch (Exception e) {
                    Log.e(TAG, "Read data error." + e.getMessage());
                    e.printStackTrace();
                }
            }
        }

        public InputStream getInputStream() {
            while (BluetoothInterface.this.inputstream == null) {

                if (BluetoothInterface.this.connecting == false) {
                    synchronized (BluetoothInterface.this.connecting) {
                        BluetoothInterface.this.mConnectThread.start();
                    }
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Log.e(TAG, "Read thread was interrupted.");
                }

            }
            Log.e(TAG, "Read got inputStream success.");
            return BluetoothInterface.this.inputstream;
        }
    }

    private class SendThread extends Thread {
        // The local server socket
        private static final String TAG = "SendThread";

        public void run() {
            Log.e(TAG, "开启发送线程。");
            while (SerialController.getInstance().getmRunFlag()) {
                Log.e(TAG, "开启发送线程while--。");
                try {
                    byte[] buffer = BluetoothInterface.this.messageQueue.take();
                    this.checkOutputStream().write(buffer);
                    this.checkOutputStream().flush();
                    Log.e(TAG, "write buffer 【" + ResponseMessageUtils.bytesToHex(buffer) + "】 size:" + buffer.length);
                } catch (InterruptedException e) {
                    Log.e(TAG, "Sending thread was interrupted.");
                } catch (IOException ee) {
                    Log.e(TAG, "IOException error.");
                }
            }
        }

        public OutputStream checkOutputStream() {
            while (BluetoothInterface.this.outputstream == null) {

                if (BluetoothInterface.this.connecting == false) {
                    synchronized (BluetoothInterface.this.connecting) {
                        BluetoothInterface.this.mConnectThread.start();
                    }
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Log.e(TAG, "Sleep thread was interrupted.");
                }

            }
            return BluetoothInterface.this.outputstream;
        }

    }

    @Override
    public void stop() {
        close(inputstream, outputstream);
        close(socket);
    }
}
